#include "AD7793.h"
#include "Delay.h"

// 模拟SPI宏定义（参考示例程序）
#define AD7793_SCLK_H GPIO_SetBits(AD7793_SCLK_PORT, AD7793_SCLK_PIN)
#define AD7793_SCLK_L GPIO_ResetBits(AD7793_SCLK_PORT, AD7793_SCLK_PIN)
#define AD7793_CS_H GPIO_SetBits(AD7793_CS_PORT, AD7793_CS_PIN)
#define AD7793_CS_L GPIO_ResetBits(AD7793_CS_PORT, AD7793_CS_PIN)
#define AD7793_SDI_H GPIO_SetBits(AD7793_SDI_PORT, AD7793_SDI_PIN)
#define AD7793_SDI_L GPIO_ResetBits(AD7793_SDI_PORT, AD7793_SDI_PIN)
#define AD7793_SDO GPIO_ReadInputDataBit(AD7793_SDO_PORT, AD7793_SDO_PIN)

/**
  * 函    数：AD7793复位（模拟SPI）
  * 参    数：无
  * 返 回 值：无
  */
void AD7793_Reset(void)
{
    uint8_t ResetTime = 50;
    
    AD7793_SCLK_H;
    AD7793_CS_L;
    AD7793_SDI_H;
    
    while (ResetTime--) {
        AD7793_SCLK_L;
        Delay_us(200);
        AD7793_SCLK_H;
        Delay_us(200);
    }
    
    AD7793_CS_H;
}

/**
  * 函    数：AD7793写字节（模拟SPI）
  * 参    数：data 要写入的数据
  * 返 回 值：无
  */
void AD7793_WriteByte(uint8_t data)
{
    uint8_t i;
    
    AD7793_SCLK_H;
    AD7793_CS_L;
    AD7793_SDI_L;
    
    for (i = 0; i < 8; i++) {
        AD7793_SCLK_L;
        if (data & 0x80) {
            AD7793_SDI_H;
        } else {
            AD7793_SDI_L;
        }
        Delay_us(100);
        AD7793_SCLK_H;
        Delay_us(100);
        data = data << 1;
    }
}

/**
  * 函    数：AD7793读取24位数据（模拟SPI）
  * 参    数：无
  * 返 回 值：24位ADC数据
  */
uint32_t AD7793_ReadData(void)
{
    uint32_t DATA = 0;
    uint8_t i;
    
    AD7793_SDI_L;
    AD7793_CS_L;
    AD7793_SCLK_H;
    
    for (i = 0; i < 24; i++) {
        DATA <<= 1;
        AD7793_SCLK_L;
        Delay_us(100);
        if (AD7793_SDO) {
            DATA |= 0x01;
        }
        AD7793_SCLK_H;
        Delay_us(100);
    }
    
    return DATA;
}

/**
  * 函    数：AD7793读取8位数据（模拟SPI）
  * 参    数：无
  * 返 回 值：8位数据
  */
uint8_t AD7793_ReadByte(void)
{
    uint8_t DATA = 0;
    uint8_t i;
    
    AD7793_SDI_L;
    AD7793_CS_L;
    AD7793_SCLK_H;
    
    for (i = 0; i < 8; i++) {
        DATA <<= 1;
        AD7793_SCLK_L;
        Delay_us(100);
        if (AD7793_SDO) {
            DATA |= 0x01;
        }
        AD7793_SCLK_H;
        Delay_us(100);
    }
    
    return DATA;
}

/**
  * 函    数：检查AD7793数据是否准备好
  * 参    数：无
  * 返 回 值：1-数据准备好，0-数据未准备好
  */
uint8_t AD7793_DataReady(void)
{
    return (GPIO_ReadInputDataBit(AD7793_DRDY_PORT, AD7793_DRDY_PIN) == RESET);
}

/**
  * 函    数：获取AD7793 ID
  * 参    数：无
  * 返 回 值：AD7793 ID
  */
uint8_t AD7793_GetID(void)
{
    uint8_t ID;
    AD7793_WriteByte(AD7793_REG_ID);
    ID = AD7793_ReadByte();
    return ID;
}

/**
  * 函    数：AD7793初始化（包含内部校准）
  * 参    数：无
  * 返 回 值：无
  */
void AD7793_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置CS引脚（PA4）
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = AD7793_CS_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(AD7793_CS_PORT, &GPIO_InitStructure);
    
    // 配置SCLK引脚（PA5）
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = AD7793_SCLK_PIN;
    GPIO_Init(AD7793_SCLK_PORT, &GPIO_InitStructure);
    
    // 配置SDI引脚（PA6）
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = AD7793_SDI_PIN;
    GPIO_Init(AD7793_SDI_PORT, &GPIO_InitStructure);
    
    // 配置SDO引脚（PA7）
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = AD7793_SDO_PIN;
    GPIO_Init(AD7793_SDO_PORT, &GPIO_InitStructure);
    
    // 配置DRDY引脚（PA3）
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = AD7793_DRDY_PIN;
    GPIO_Init(AD7793_DRDY_PORT, &GPIO_InitStructure);
    
    // CS引脚拉高（空闲状态）
    GPIO_SetBits(AD7793_CS_PORT, AD7793_CS_PIN);
    
    Delay_ms(100); // 等待AD7793上电稳定
    
    // 复位AD7793
    AD7793_Reset();
    Delay_ms(200);
    
    // 设置IO寄存器
    AD7793_WriteByte(AD7793_REG_IO);
    AD7793_WriteByte(0x06);
    
    // 设置配置寄存器
    AD7793_WriteByte(AD7793_REG_CONF);
    AD7793_WriteByte(0x10); // Gain 1
    AD7793_WriteByte(0x10); // External Reference
    
    // 设置模式寄存器 - 内部零标度校准
    AD7793_WriteByte(AD7793_REG_MODE);
    AD7793_WriteByte(0x80); // 内部零标度校准
    AD7793_WriteByte(0x4F); // 12.5Hz
    Delay_ms(800);
    
    // 等待校准完成
    while (AD7793_DataReady());
    
    // 设置模式寄存器 - 内部满标度校准
    AD7793_WriteByte(AD7793_REG_MODE);
    AD7793_WriteByte(0xA0); // 内部满标度校准
    AD7793_WriteByte(0x4F); // 12.5Hz
    Delay_ms(800);
    
    // 等待校准完成
    while (AD7793_DataReady());
}

/**
  * 函    数：AD7793热电偶通道初始化
  * 参    数：无
  * 返 回 值：无
  */
void AD7793_ThermocoupleInit(void)
{
    AD7793_Reset();
    Delay_ms(20);
    
    // 设置IO寄存器
    AD7793_WriteByte(AD7793_REG_IO);
    AD7793_WriteByte(0x0A); // 设置420uA电流源
    
    // 设置配置寄存器
    AD7793_WriteByte(AD7793_REG_CONF);
    AD7793_WriteByte(0x45); // Gain = 32
    AD7793_WriteByte(0x90); // 通道选择
    
    // 设置模式寄存器
    AD7793_WriteByte(AD7793_REG_MODE);
    AD7793_WriteByte(0x00); // 连续转换模式
    AD7793_WriteByte(0x0B); // 12.5Hz数据输出
}

/**
  * 函    数：AD7793 PT100通道初始化
  * 参    数：无
  * 返 回 值：无
  */
void AD7793_PT100Init(void)
{
    AD7793_Reset();
    Delay_ms(20);
    
    // 设置IO寄存器
    AD7793_WriteByte(AD7793_REG_IO);
    AD7793_WriteByte(0x0A); // 设置420uA电流源
    
    // 设置配置寄存器
    AD7793_WriteByte(AD7793_REG_CONF);
    AD7793_WriteByte(0x40); // Gain = 1
    AD7793_WriteByte(0x11); // 通道选择
    
    // 设置模式寄存器
    AD7793_WriteByte(AD7793_REG_MODE);
    AD7793_WriteByte(0x00); // 连续转换模式
    AD7793_WriteByte(0x0B); // 12.5Hz数据输出
}

/**
  * 函    数：获取热电偶电压值
  * 参    数：无
  * 返 回 值：热电偶电压（伏特）
  */
float AD7793_GetThermocoupleValue(void)
{
    float voltage;
    uint32_t data;
    int32_t data_signed;
    
    // 等待数据准备好
    while (AD7793_DataReady());
    
    // 读取数据
    AD7793_WriteByte(AD7793_REG_DATA);
    data = AD7793_ReadData();
    
    // 数据处理（参考示例程序）
    data ^= 0xFFFFFF;
    data &= 0xFFFFFF;
    data_signed = 0x7FFFFF - data;
    
    // 转换为电压值
    voltage = data_signed * 1.17f; // Vref = 1.17V
    voltage /= 0x7FFFFF; // 24位ADC满量程
    voltage /= 32; // Gain = 32
    
    return voltage;
}

/**
  * 函    数：获取PT100温度值
  * 参    数：无
  * 返 回 值：PT100温度（摄氏度）
  */
float AD7793_GetPT100Temperature(void)
{
    float temperature;
    float resistance;
    uint32_t data;
    
    // 等待数据准备好
    while (AD7793_DataReady());
    
    // 读取数据
    AD7793_WriteByte(AD7793_REG_DATA);
    data = AD7793_ReadData() - 0x800000; // 减去偏移
    
    // 转换为电阻值
    temperature = data;
    temperature /= 0x7FFFFF; // 归一化
    resistance = temperature * 402; // 转换为电阻值
    
    // 转换为温度值（A级PT100）
    temperature = (resistance - 100) / 0.385055;
    
    return temperature;
}

/**
  * 函    数：读取原始数据（调试用）
  * 参    数：无
  * 返 回 值：24位原始数据
  */
uint32_t AD7793_ReadRawData(void)
{
    uint32_t data;
    
    // 等待数据准备好
    while (AD7793_DataReady());
    
    // 读取数据
    AD7793_WriteByte(AD7793_REG_DATA);
    data = AD7793_ReadData();
    
    return data;
}

/**
  * 函    数：测试SPI通信（调试用）
  * 参    数：无
  * 返 回 值：无
  */
void AD7793_TestSPI(void)
{
    // 模拟SPI不需要测试函数
}